﻿#include <QMutex>
#include <QSerialPort>
#include <QTimer>
#include <QDebug>
#include "serial.h"

QScopedPointer<Serial> Serial::self;

Serial *Serial::Insatnce()
{
    if (self.isNull())
    {
        static QMutex mutex;
        QMutexLocker locker(&mutex);
        if (self.isNull()) {
            self.reset(new Serial);
        }
    }
    return self.data();
}

Serial::Serial(QObject *parent)
    : QObject{parent}
{
    init();
}

void Serial::init()
{
    serialCom = new QSerialPort();
    connect(serialCom,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
}

QString Serial::byteArrayToHexStr(const QByteArray &data)
{
    QString temp = "";
    QString hex = data.toHex();
    for (int i = 0; i < hex.length(); i = i + 2) {
        temp += hex.mid(i, 2) + " ";
    }

    return temp.trimmed().toUpper();
}

QByteArray Serial::hexStrToByteArray(const QString &data)
{
    QByteArray senddata;
    int hexdata, lowhexdata;
    int hexdatalen = 0;
    int len = data.length();
    senddata.resize(len / 2);
    char lstr, hstr;

    for (int i = 0; i < len;) {
        hstr = data.at(i).toLatin1();
        if (hstr == ' ') {
            i++;
            continue;
        }

        i++;
        if (i >= len) {
            break;
        }

        lstr = data.at(i).toLatin1();
        hexdata = hexStrToChar(hstr);
        lowhexdata = hexStrToChar(lstr);

        if ((hexdata == 16) || (lowhexdata == 16)) {
            break;
        } else {
            hexdata = hexdata * 16 + lowhexdata;
        }

        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }

    senddata.resize(hexdatalen);
    return senddata;
}

char Serial::hexStrToChar(char data)
{
    if ((data >= '0') && (data <= '9')) {
        return data - 0x30;
    } else if ((data >= 'A') && (data <= 'F')) {
        return data - 'A' + 10;
    } else if ((data >= 'a') && (data <= 'f')) {
        return data - 'a' + 10;
    } else {
        return (-1);
    }
}

bool Serial::isOpen(const serialInfo &info)
{
    if(serialCom->isOpen())
        return true;
    serialCom->setPortName(info.portName);
    if (serialCom->open(QIODevice::ReadWrite)) {
        serialCom->setBaudRate(static_cast<QSerialPort::BaudRate>(info.baudRate.toInt()));
        serialCom->setDataBits(static_cast<QSerialPort::DataBits>(info.dataBit.toInt()));
        serialCom->setParity(static_cast<QSerialPort::Parity>(info.parity.toInt()));
        serialCom->setStopBits(static_cast<QSerialPort::StopBits>(info.stopBit.toInt()));
        serialCom->setFlowControl(static_cast<QSerialPort::FlowControl>(info.flowControl.toInt()));
        emit msgTip(2,"打开成功");
    } else {
        emit msgTip(2,"打开失败");
    }
    return serialCom->isOpen();
}

void Serial::close()
{
    if(serialCom->isOpen())
        serialCom->close();
    emit msgTip(2,"串口关闭");
}

void Serial::onReadyRead()
{
    if(serialCom->bytesAvailable() <= 0) {
        return;
    }
    QByteArray temp = serialCom->readAll();

    QString data = byteArrayToHexStr(temp);

    emit msgTip(0,data);
}

void Serial::onSendData(const QString &data)
{
    if(!serialCom->isOpen())
        return;
    QByteArray sendData = hexStrToByteArray(data);
    serialCom->write(sendData);
    emit msgTip(1,data);
}

